﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
  <title>Critical</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <link href="../css/commands.css" type="text/css" rel="stylesheet">
  <link media="print" href="../css/print.css" type="text/css" rel="stylesheet">
  <meta content="MSHTML 6.00.6000.16608" name="GENERATOR">
</head>
<body>
<h1>Critical （关键线程）</h1>
<p>防止 <a href="../misc/Threads.htm">current thread</a>
（当前线程）被其他线程中断。</p>
<p class="CommandSyntax">Critical [, Off]<br>
Critical 50 <em>;&nbsp;请看底部的注释 <a href="#Interval">bottom of remarks</a>. </em></p>
<p>如果第一个参数被省略（或者是 On），则 <a href="../misc/Threads.htm">current
thread</a>
（当前的线程）被设置为 Critical （关键线程）这就意味着他不会被其他的线程所中断。如果第一个参数是Off(或者0，在 1.0.48+ 版本中)，则当前的线程忽略 <a href="../misc/Threads.htm">"Thread
Interrupt"</a> 的设置，立即被设置为可以中断的状态。</p>
<p>不同于 <a href="../misc/Threads.htm">high-priority</a>
（高优先级线程），如果在Critical 状态的线程运行中产生了另一个事件，则该事件不会被忽略。例如，当用户按下一个热键 <a href="../Hotkeys.htm">hotkey</a>，
但该热键的线程正以 Critical 状态运行，这时用户按下的热键会被缓冲，直到当前的线程结束或者被设置为可以中断的非关键状
态，这时用户按下的热键才会被一个新的线程所执行。</p>
<p>一个处于 Critical 状态的线程也会被紧急事件所中断。紧急事件包括：1） <a href="OnExit.htm">OnExit</a> 子
程序；2）任意一个监听的消息值小于0x312的 <a href="OnMessage.htm">OnMessage()</a> 函数（或是被这些消息所触发的 <a href="RegisterCallback.htm">callback</a>
函数）；3）任意一个被当前线程自己所间接触发的 （通过 <a href="PostMessage.htm">SendMessage</a>
或 <a href="DllCall.htm">DllCall</a>&nbsp;等函数所触发）
为了避免被这些函数的中断，可以临时的关闭这些函数。</p>
<p>当缓冲事件等待被线程执行时，使用"Critical
Off"不能够立即中断当前的线程。相反，执行中断平均需要花费5毫秒。这样在中断前，至少在"Critical Off"下面的一行代码
99.999%可能会被执行。你可以通过利用 <a href="Sleep.htm">Sleep
-1</a> 或用 <a href="WinWait.htm">WinWait</a> 等待一个不存在的窗口等方法，进行强制中断。</p>
<p>当一个 <a href="MsgBox.htm">MsgBox</a>
或者其他对话框显示时，会中断一个Critical状态的线程，而不同于 <a href="Thread.htm">"Thread
Interrupt"</a>，线程会在对话框关闭时恢复Critical 状态。</p>
<p>关于如何保存和还原当前 Critical 的设置，请参考 <a href="../Variables.htm#IsCritical">A_IsCritical</a> 。因为 Critical
状态是一个特殊设置的线程，当线程结束，接下来运行的线程或者重新运行的线程（如果有的话）不会再以Critical&nbsp;状态运行。所以不需要在结束一个线程后再声明"Critical Off"。</p>
<p>如果在自动运行片段（也就是脚本的最上面的一段代码）没有声明 Critical ，所有的线程不会以 Critical&nbsp;
状态运行（尽管可以设置 <a href="Thread.htm">"Thread
Interrupt"</a>&nbsp;来实现）。相反，如果在自动运行片段声明了Critical
且不曾关闭Critical状态，则每个新运行的线程（如 <a href="../Hotkeys.htm">hotkey</a>，<a href="Menu.htm">custom
menu item</a> （自定义菜单项）和 <a href="SetTimer.htm">timed</a>
子程序）都会以 Critical&nbsp;状态运行。</p>
<p>"<a href="Thread.htm">Thread
NoTimers</a>" 命令和 Critical 相似，除了他可以防止被 <a href="SetTimer.htm">timers</a>
所中断。</p>
<p>在v1.0.47 及其以后的版本中，设置 Critical 状态同时会对 <a href="../misc/Threads.htm">current
thread</a> （当前线程 ）产生 <a href="SetBatchLines.htm"><em>SetBatchLines
-1</em></a> 效果。</p>
<p><a name="Interval"></a>在v1.0.47及其以后的版本中，第一参数
指定为一个正数（例如<em>Critical 30</em> ），表示该线程为关键线程，但是也改变了检查
内部消息队列的间隔时间。如果第一个参数为On，会以默认16毫秒间隔检查，当参数为Off则以5毫秒间隔检查。增加推迟消息/事件的延时间隔，可
以给 <a href="../misc/Threads.htm">current thread</a>
（当前线程 ）更多的时间来结束。这样可以减少因为&ldquo;线程正在运行&rdquo;而导致消息 <a href="OnMessage.htm">OnMessage()</a> 和 界面事件 <a href="Gui.htm#DefaultWin">GUI events</a> 丢失的可能性。然而，例如 <a href="Sleep.htm">Sleep</a> 和 <a href="WinWait.htm">WinWait</a>
命令会默认检查消息而忽略这个设置（一个解决方案是 <em>DllCall("Sleep", Uint, 500)</em>）。注意：检
查消息的时间间隔增加的太多有可能减少各种事件的响应，如 <a href="Gui.htm">GUI</a>
窗口的重绘。</p>
<h3>相关命令</h3>
<p><a href="Thread.htm">Thread (command), </a><a href="../misc/Threads.htm">Threads</a> , <a href="_MaxThreadsPerHotkey.htm">#MaxThreadsPerHotkey</a>,
<a href="_MaxThreadsBuffer.htm">#MaxThreadsBuffer</a>,
<a href="OnMessage.htm">OnMessage()</a>, <a href="RegisterCallback.htm">RegisterCallback()</a>, <a href="Hotkey.htm">Hotkey</a>, <a href="Menu.htm">Menu</a>,
<a href="SetTimer.htm">SetTimer</a></p>
<h3>示例</h3>
<pre class="NoIndent">#space:: <em>; Win+Space hotkey.</em><br>Critical<br>ToolTip 在这个提示消失之前不会再有新的线程运行<br>Sleep 3000<br>ToolTip <em>; 关闭提示</em><br>return <em>; 热键子程序结束，以下的线程不会再以关键</em>状态运行。<em></em><br><br></pre>
</body>
</html>
